﻿#pragma once

#include <afxsock.h>
#include "Const.h"
#include "Protocol.h"

// 游戏
class Game: public CSocket {
    // 棋子类型
    private: enum Piece {
        NOTHING,    // 什么也没有
        BLACK,      // 黑棋
        WHITE       // 白棋
    };

    // 状态
    private: enum Status {
        END,            // 结束
        PLAYING,        // 自己下棋中
        RIVAL_PLAYING   // 对手下棋中
    };

    private: CBrush mBlackBrush;    // 黑色画刷
    private: CWnd* mCallback;       // 回调
    private: CDC* mDrawer;          // 绘图者
    private: CWnd* mGameBoard;      // 游戏区域
    private: BOOL mIsBlack;         // 黑棋则为 TRUE，白棋则为 FALSE
    private: POINT mLastPos;        // 上一次放置棋子的位置
    private: Piece mPieces[Const::GAME_BOARD_POINT_COUNT_V][Const::GAME_BOARD_POINT_COUNT_H];   // 所有棋子
    private: CString mRivalName;    // 对手的名字
    private: Status mStatus;        // 状态
    private: CString mUsername;     // 用户名
    private: CBrush mWhiteBrush;    // 白色画刷

    public: Game(CWnd*, CDC*, CWnd*);
    public: ~Game();
    public: void AcceptInvite(LPCTSTR, BOOL);
    private: BOOL CheckHorizontal();
    private: BOOL CheckOblique1();
    private: BOOL CheckOblique2();
    private: BOOL CheckVertical();
    public: void Defeat();
    private: void DrawGameBoard();
    public: void FindUsers();
    private: void GameOver(GameOverReason);
    private: void HandleFindUsers(FindUsersResult*);
    private: void HandleGameOver(class GameOver*);
    private: void HandleInviteRequest(InviteRequest*);
    private: void HandleInviteResult(InviteResult*);
    private: void HandleLogon(LogonResult*);
    private: void HandlePutPiece(PutPiece*);
    private: void HandleQuitGame(QuitGame*);
    public: void Invite(LPCTSTR);
    private: BOOL IsWon();
    public: void Logon(LPCTSTR);
    public: void OnGameBoardClicked(int x, int y);
    private: void OnGetMessageFromServer(GomokuProtocol*);
    private: virtual void OnReceive(int);
    private: BOOL Put_Piece(BOOL, int, int);
    public: void Restart();
    private: void SendData(GomokuProtocol*, int);
    public: void Start(BOOL isBlack = TRUE);
};
